﻿@using MudBlazor
@inherits MudComponentBase

@inject IStringLocalizer<PermissionsDrawer> L

<MudDrawer Open="@Open"
           Width="400px"
           Height="100vh"
           OpenChanged="@(s => OnOpenChanged.InvokeAsync(s))"
           Anchor="Anchor.End" Elevation="1" Variant="@DrawerVariant.Temporary">
    <MudDrawerHeader>
        <MudText Typo="Typo.h5">@L["Set Permissions"]</MudText>
    </MudDrawerHeader>
    <MudStack AlignItems="AlignItems.Stretch" Class="px-5">
        <MudTextField @bind-Value="Keyword" Label="Search"
                      Margin="Margin.Dense"
                      Variant="Variant.Text"
                      Adornment="Adornment.End"
                      AdornmentIcon="@Icons.Material.Filled.Search"
                      AdornmentColor="Color.Secondary" />
    </MudStack>    @if (Permissions != null && Permissions.Any())
    {
        @foreach (var groupData in _filteredPermissionGroups)
        {
            <MudCard class="ma-4">
                <MudCardHeader>
                    <CardHeaderContent>
                        <MudStack Spacing="2">
                            <MudText Typo="Typo.body1">
                                @L[groupData.Key]
                            </MudText>
                            <MudText Typo="Typo.body2" Class="mud-text-secondary">
                                @(L[groupData.FirstItem.Description])
                            </MudText>
                        </MudStack>
                    </CardHeaderContent>
                    <CardHeaderActions>
                        <MudTooltip Text="@L["Assign / Unassign all permission set"]">
                            @if (groupData.Items.Any(x => x.IsInherit))
                            {
                                <MudIconButton Disabled="true" Icon="@Icons.Material.Filled.AutoFixHigh" Color="Color.Default" />
                            }
                            else
                            {
                                <MudIconButton Disabled="@Waiting" 
                                               Icon="@Icons.Material.Filled.AutoFixHigh" 
                                               Color="Color.Default" 
                                               OnClick="@(() => OnAssignAll(groupData.Key))" />
                            }
                        </MudTooltip>
                    </CardHeaderActions>
                </MudCardHeader>
                <MudCardContent>
                    <MudList Dense="true" Class="pa-0" T="string">
                    @foreach (var permission in groupData.Items)
                    {
                        <MudListItem Class="py-1 px-0">
                            <div class="d-flex align-center w-100">
                                <MudCheckBox Dense="true"
                                             T="bool"
                                             Size="Size.Small"
                                             Value="@permission.Assigned"
                                             Disabled="@permission.IsInherit"
                                                 ValueChanged="@(s => OnCheckChanged(s,permission))"
                                             Color="@(permission.IsInherit ? Color.Default : Color.Primary)">
                                </MudCheckBox>
                                <div class="d-flex flex-column ml-2">
                                    <MudText Typo="Typo.body2">
                                        @L[permission.Name]
                                    </MudText>
                                    @if (!string.IsNullOrEmpty(permission.HelpText))
                                    {
                                        <MudText Typo="Typo.caption" Class="mud-text-secondary">
                                            @L[permission.HelpText]
                                        </MudText>
                                    }
                                </div>
                            </div>
                        </MudListItem>
                    }
                    </MudList>
                </MudCardContent>
            </MudCard>
        }

        @if (!_filteredPermissionGroups.Any())
        {
            <MudAlert Severity="Severity.Info" Class="ma-4">
                @L["No permissions match your search criteria"]
            </MudAlert>
        }
    }
    else
    {
        <MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="my-7" />
    }
</MudDrawer>

@code {
    [EditorRequired][Parameter] public IList<PermissionModel>? Permissions { get; set; }

    [EditorRequired][Parameter] public bool Open { get; set; } = default!;

    [EditorRequired][Parameter] public EventCallback<PermissionModel> OnAssignChanged { get; set; }

    [EditorRequired][Parameter] public EventCallback<List<PermissionModel>> OnAssignAllChanged { get; set; }

    [EditorRequired][Parameter] public EventCallback<bool> OnOpenChanged { get; set; }

    [Parameter] public bool Waiting { get; set; }

    private string _keyword = string.Empty;
    private List<PermissionGroupData> _filteredPermissionGroups = new();

    private string Keyword
    {
        get => _keyword;
        set
        {
            if (_keyword != value)
            {
                _keyword = value;
                UpdateFilteredPermissions();
            }
        }
    }

    protected override void OnParametersSet()
    {
        if (Permissions != null)
        {
            UpdateFilteredPermissions();
        }
    }
    private void OnCheckChanged(bool isChecked, PermissionModel? permission)
    {
        if (permission == null) return;
        permission.Assigned = isChecked;
        OnAssignChanged.InvokeAsync(permission);
    }

    private void UpdateFilteredPermissions()
    {
        _filteredPermissionGroups = Permissions?
            .Where(x => string.IsNullOrEmpty(_keyword) || 
                        x.Group!.Contains(_keyword, StringComparison.InvariantCultureIgnoreCase) || 
                        x.Name.Contains(_keyword, StringComparison.InvariantCultureIgnoreCase) ||
                        x.Description!.Contains(_keyword, StringComparison.InvariantCultureIgnoreCase))
            .GroupBy(x => x.Group)
            .Select(group => new PermissionGroupData(
                group.Key!,
                group.OrderBy(x => x.Name).ToList(),
                group.First().Description
            ))
            .OrderBy(x => x.Key)
            .ToList() ?? new List<PermissionGroupData>();
    }

    private async Task OnAssignAll(string? groupName)
    {
        if (string.IsNullOrEmpty(groupName) || Permissions == null)
            return;

        var list = new List<PermissionModel>();
        var permissionsInGroup = Permissions.Where(t => t.Group == groupName && !t.IsInherit).ToList();
        
        // Check if all are currently assigned or not - if mixed, we'll make them all assigned
        var allAssigned = permissionsInGroup.All(p => p.Assigned);
        
        foreach (var permission in permissionsInGroup)
        {
            permission.Assigned = !allAssigned;
            list.Add(permission);
        }
        
        await OnAssignAllChanged.InvokeAsync(list);
    }

    // Helper class to hold grouped permission data
    private class PermissionGroupData
    {
        public string Key { get; }
        public List<PermissionModel> Items { get; }
        public PermissionModel FirstItem => Items.First();
        public string Description { get; }
        
        public PermissionGroupData(string key, List<PermissionModel> items, string description)
        {
            Key = key;
            Items = items;
            Description = description;
        }
    }
}